package core

import (
	"context"
	"errors"
	"fmt"
	"google.golang.org/grpc/metadata"
	"server/component"
	"server/component/errorx"
	"server/im/entity"
	"server/im/protocol"
	pb "server/im/rpc"
	"server/service"
)

type rpcServer struct {
	pb.UnimplementedHubServer
	hub *Hub
}

func (s *rpcServer) Chat(stream pb.Hub_ChatServer) error {

	// 提取请求上下文中的元数据（Headers）
	md, ok := metadata.FromIncomingContext(stream.Context())
	if !ok {
		return errors.New("missing metadata")
	}

	// 获取 Authorization 信息
	header := md["gateway"]
	if len(header) == 0 {
		return errors.New("missing header")
	}

	// 验证 Bearer Token
	gatewayId := header[0]

	fmt.Println("gateway link hub", gatewayId)

	fmt.Println("s1", stream)

	//s1 := &stream

	g := newGateway(gatewayId, s.hub, stream)

	fmt.Println("g1", g)
	fmt.Println("gs", g.stream)

	s.hub.addGateway(g)

	return nil
}

func (s rpcServer) ChatLogin(ctx context.Context, in *pb.CoreInModel) (*pb.CoreOutModel, error) {

	//msgType := in.GetMsgType()
	gatewayId := in.GetGatewayId()
	gatewayIn := in.GetGatewayInModel()
	//
	//fmt.Println("chat login->", in, id, msgType, gatewayIn)

	inputMap := make(map[string]string)
	err := component.JsonDecode(gatewayIn.Data, &inputMap)
	if err != nil {
		component.Log.Error("data err" + string(gatewayIn.Data))
		return nil, errorx.New(300, "data err")
	}
	token, ok := inputMap["token"]
	if ok != true {
		component.Log.Error("no token" + string(gatewayIn.Data))
		return nil, errorx.New(301, "no token")
	}

	userModel, err := service.Us.ImLogin(ctx, &service.ImLoginOpt{
		Token:   token,
		Ip:      gatewayIn.Ip,
		Gateway: gatewayId,
	})
	if err != nil {
		component.Log.Error(err)
		return nil, errorx.New(302, "login err")
	}
	//登录成功事件
	component.DefaultEventBus.Publish(protocol.EventUserLogin, entity.EventRequest{
		Data: entity.UserModel{
			Id:    userModel.Id,
			Name:  userModel.Name,
			Token: userModel.Token,
			Uuid:  userModel.Uuid,
			Ip:    gatewayIn.Ip,
		},
		GatewayId:   gatewayId,
		RespondChan: s.hub.respondChan,
	})

	//登录结果
	userData, _ := component.JsonEncode(userModel)
	return &pb.CoreOutModel{
		GatewayOutModel: &pb.GatewayOutModel{
			Data: userData,
			Cmd:  0,
		},
		GatewayId:    gatewayId,
		MsgType:      0,
		ReceiverType: 0,
		Clients:      nil,
	}, nil
}

func (s rpcServer) ChatOffline(ctx context.Context, in *pb.CoreInModel) (*pb.CoreOutModel, error) {

	//msgType := in.GetMsgType()
	gatewayId := in.GetGatewayId()
	gatewayIn := in.GetGatewayInModel()

	fmt.Println("offline---------->", in)

	//断开连接事件
	component.DefaultEventBus.Publish(protocol.EventUserLostConnect,
		entity.EventRequest{
			Data: entity.UserModel{
				Uuid: gatewayIn.UserUni,
				Ip:   gatewayIn.Ip,
			},
			GatewayId:   gatewayId,
			RespondChan: s.hub.respondChan,
		})

	return nil, nil
}
